<template>
  <div
    :id="bgContainer"
    @click="startPhone"
    :key="connectInfo.phone_id"
    :class="['phone', 'connecting']"
  >
    <div
      :class="`${statusMap[status]}-dot`"
      class="status-tip"
      v-if="status !== statusMap['connected']"
    >
      <span class="dot"></span>
      {{ statusTip[status] }}
    </div>
    <img
      :id="`phone-view-container-${connectInfo.phone_id}`"
      class="phone-view"
    />
    <el-dialog
      class="phone-dialog"
      v-model="phoneVisible"
      :closeOnClickModal="false"
      :appendToBody="true"
      :closeOnPressEscape="false"
      title="云手机"
      center
      @close="exitPhone"
    >
      <div
        class="wallpaper"
        :id="fullscreenContainer"
        :style="{
          flexDirection: rotatePlayerClass === 'PORTRAIT' ? 'row' : 'column',
        }"
      >
        <div
          :class="rotatePlayerClass"
          class="phone-container"
          :id="phoneContainer"
        ></div>
      </div>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import { ref, toRef } from 'vue';
import CPHCloudApp from '../static/CPHCloudApp';
import StartScreenPrint from '../static/StartScreenPrint';
import { ElMessageBox } from 'element-plus';
export default {
  name: 'phoneViewComp',
  props: ['connectInfo'],
  setup(props) {
    const loading = ref(true);
    const cloudapp = ref(null);
    const SrceenPrintApp = ref(null);
    const phoneViewContainer = ref(null);
    const phoneVisible = ref(false);
    const retryTip = ref('');
    const status = ref('unconnect');
    const rotatePlayerClass = ref('PORTRAIT');
    const bgContainer = ref('bg-container');
    const statusMap = {
      unconnect: 'unconnect',
      disconnect: 'disconnect',
      connected: 'connected',
      connecting: 'connecting',
      exceedLimit: 'exceedLimit',
    };
    const statusTip = {
      unconnect: '未连接，未开通CAE功能',
      disconnect: '连接断开，连接失败或超时自动断开',
      exceedLimit: '连接超出最大限制',
      connected: '已连接',
      connecting: '连接中',
    };
    return {
      loading,
      cloudapp,
      SrceenPrintApp,
      retryTip,
      status,
      statusMap,
      statusTip,
      phoneVisible,
      phoneViewContainer,
      rotatePlayerClass,
      bgContainer,
      connectInfo: props.connectInfo,
      phoneContainer: 'phone-container' + props.connectInfo?.phone_id,
      fullscreenContainer: 'fullscreen-container' + props.connectInfo?.phone_id,
    };
  },
  created() {},
  mounted() {
    if (this.connectInfo?.access_info) {
      window.open(
        'https://' +
          [
            this.connectInfo.access_info.access_ip,
            this.connectInfo.access_info.access_port,
          ].join(':'),
        '_black',
      );
      this.StartScreenPrint();
    }
  },
  methods: {
    StartScreenPrint() {
      this.status = this.statusMap.connecting;
      const cloudIp = this.connectInfo.access_info.access_ip;
      const cloudPort = this.connectInfo.access_info.access_port;
      const cloudPhoneParams = {
        ip: cloudIp,
        port: cloudPort,
        session_id: this.connectInfo.access_info.session_id,
        background_timeout: '0', // 后台运行超时时间
        available_playtime: '0', // 试玩时间
        touch_timeout: 0, // 未触控超时时间
        connect_uri: 'wss://' + [cloudIp, cloudPort].join(':'),
        channelType: 'WebSocket',
        ticket: this.connectInfo.access_info.ticket,
        aes_key: this.connectInfo.phone_id,
        auth_ts: this.connectInfo.access_info.timestamp,
        _debug: true,
        auto_rotate: true,
        libPath: window.location.origin + '/lib/', // 配置库文件地址
        microPhoneOutputType: 'OPUS', // PCM或OPUS
        fullscreenId: this.fullscreenContainer, // 全屏DOM ID
        media_config: {
          stream_width: '320',
          stream_height: '640',
        },
      };

      if (StartScreenPrint.isSupport()) {
        this.SrceenPrintApp = new StartScreenPrint(
          this.bgContainer,
          cloudPhoneParams,
        );

        this.SrceenPrintApp.on('phoneViewChange', (event, data) => {
          if (!this.phoneViewContainer) {
            this.phoneViewContainer = document.getElementById(
              `phone-view-container-${this.connectInfo.phone_id}`,
            );
            this.phoneViewContainer.style.setProperty('display', 'block');
          }
          this.phoneViewContainer.src = data;
        });

        this.SrceenPrintApp.on('appStateChange', (event, data) => {
          console.log(event, data);
          var state = data && data.state;
          var STATE_CONFIG = {
            STARTED: 2048,
            RESUMED: 5120,
            MEDIA_CONFIG_SUCCESS: 8448,
            RETRY_SUCCESS: 3072,
            BACK_HOME: 6400,
          };

          var normalStates = [
            STATE_CONFIG.STARTED,
            STATE_CONFIG.RESUMED,
            STATE_CONFIG.MEDIA_CONFIG_SUCCESS,
            STATE_CONFIG.BACK_HOME,
            STATE_CONFIG.RETRY_SUCCESS,
          ];
          if (normalStates.includes(state)) {
            this.status = this.statusMap.connected;
            return;
          }
          this.showAlertTip(data);
        });
      }
    },

    showAlertTip(data) {
      const startSuccessState = 512;
      const exceedLimit = 770;
      if (data.state === startSuccessState) {
        this.status = this.statusMap.connecting;
        return;
      }
      if (data.tip) {
        if (data.state === exceedLimit) {
          this.status = this.statusMap.exceedLimit;
        } else {
          this.status = this.statusMap.disconnect;
        }
        if (this.phoneViewContainer) {
          this.phoneViewContainer.style.setProperty('display', 'none');
        }
      }
    },

    connectCloudPhone() {
      const that = this;
      const cloudIp = this.connectInfo.access_info.access_ip;
      const cloudPort = this.connectInfo.access_info.access_port;
      const cloudPhoneParams = {
        ip: cloudIp,
        port: cloudPort,
        session_id: this.connectInfo.access_info.session_id,
        background_timeout: '0', // 后台运行超时时间
        available_playtime: '0', // 试玩时间
        touch_timeout: 0, // 未触控超时时间
        connect_uri: 'wss://' + [cloudIp, cloudPort].join(':'),
        channelType: 'WebSocket',
        ticket: this.connectInfo.access_info.ticket,
        aes_key: this.connectInfo.phone_id,
        auth_ts: this.connectInfo.access_info.timestamp,
        _debug: true,
        auto_rotate: true,
        libPath: window.location.origin + '/lib/', // 配置库文件地址
        microPhoneOutputType: 'OPUS', // PCM或OPUS
        fullscreenId: this.fullscreenContainer, // 全屏DOM ID
      };

      if (CPHCloudApp.isSupport()) {
        const cloudapp = new CPHCloudApp(this.phoneContainer, cloudPhoneParams);
        cloudapp.on('appStateChange', function (event, data) {
          console.log(event, data);
          var state = data && data.state;
          var STATE_CONFIG = {
            STARTED: 2048,
            RESUMED: 5120,
            MEDIA_CONFIG_SUCCESS: 8448,
            RETRY_SUCCESS: 3072,
            BACK_HOME: 6400,
          };

          var normalStates = [
            STATE_CONFIG.STARTED,
            STATE_CONFIG.RESUMED,
            STATE_CONFIG.MEDIA_CONFIG_SUCCESS,
            STATE_CONFIG.BACK_HOME,
            STATE_CONFIG.RETRY_SUCCESS,
          ];
          that.loading = !normalStates.includes(state);
          that.showAlertModal(data);
        });

        cloudapp.on('netStateChange', function (event: any, data: any) {
          that.delayTime = data.delay;
        });

        // 音量设置，范围为 0 ~ 100
        cloudapp.setVolume(60);

        cloudapp.on('audioStateChange', function (event: any, data: any) {
          console.log(event, data);
        });

        cloudapp.on('cloudAppData', function (event, data) {
          var typedArray = new Uint8Array(data);
          var str = this.decodeUTF8(typedArray);
          console.log(event, str);
        });

        cloudapp.on('rotatePlayer', function (event: any, data: any) {
          that.rotatePlayerClass =
            data.orientation === 'PORTRAIT' ? 'PORTRAIT' : 'LANDSCAPE';
          that.phoneControlClass =
            data.orientation === 'PORTRAIT'
              ? 'phone-ontrol-PORTRAIT'
              : 'phone-control-LANDSCAPE';
        });

        this.cloudapp = cloudapp;
        window.sendDataToCloudApp = function (str) {
          var utf8Array = this.encodeUTF8(str);
          var typedArray = new Uint8Array(utf8Array);
          this.cloudapp.sendDataToCloudApp(typedArray.buffer);
        };

        this.listenLocationReload();

        // 监听云机复制内容写入端侧粘贴板
        cloudapp.on('clipboardDataChange', function (event, data) {
          var save = function (e) {
            e.clipboardData.setData('text/plain', data);
            e.preventDefault();
          };
          document.addEventListener('copy', save);
          document.execCommand('copy');
          document.removeEventListener('copy', save);
        });

        // 监听端侧粘贴，获取粘贴板内容发给云机
        document.addEventListener('paste', event => {
          const pasteContent = event.clipboardData.getData('text/plain');
          cloudapp.sendClipboardData(pasteContent);
        });

        this.listenLocationReload();
      }
    },

    showAlertModal(data) {
      const startSuccessState = 512;
      // 连接成功需要关闭已显示的弹框
      if (data.state === startSuccessState && this.hasAlertModal) {
        ElMessageBox.close();
        this.hasAlertModal = false;
        return;
      }
      if (data.tip && !this.hasAlertModal) {
        this.hasAlertModal = true;
        ElMessageBox.confirm(data.tip, '提示', {
          closeOnPressEscape: false,
          closeOnClickModal: false,
          showClose: false,
          cancelButtonText: '退出',
          confirmButtonText: '重试',
        })
          .then(() => {
            this.cloudapp.exit();
            this.cloudapp = null;
            setTimeout(() => {
              this.connectCloudPhone();
            }, 0);
          })
          .catch(() => {
            this.phoneVisible = false;
          });
      }
    },

    sendDataToCloudApp(str) {
      var utf8Array = this.encodeUTF8(str);
      var typedArray = new Uint8Array(utf8Array);
      this.cloudapp.sendDataToCloudApp(typedArray.buffer);
    },

    listenLocationReload() {
      document.addEventListener('visibilitychange', () => {
        const isFirstTrust = sessionStorage.getItem('isFirstTrust');
        if (document.visibilityState === 'visible' && isFirstTrust === 'true') {
          location.reload();
          sessionStorage.setItem('isFirstTrust', 'false');
        }
      });
    },

    startPhone() {
      if (this.connectInfo?.access_info) {
        this.phoneVisible = true;
        this.SrceenPrintApp.exit();
        this.status = this.statusMap.connected;
        this.SrceenPrintApp = null;
        this.connectCloudPhone();
      }
    },

    exitPhone() {
      if (this.cloudapp) {
        this.cloudapp.exit();
        this.cloudapp = null;
        this.StartScreenPrint();
      }
    },
  },

  beforeUnmount() {
    if (this.cloudapp) {
      this.cloudapp.exit();
    }
    if (this.SrceenPrintApp) {
      this.SrceenPrintApp.exit();
    }
  },
};
</script>

<style scoped lang="less">
.phone {
  position: relative;
  :deep(.el-loading-mask) {
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-round);
  }
}

.connecting {
  background-image: url('../assets/phoneConnecting.svg');
  background-size: contain;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

.phone-container {
  padding: 20px;
}

.phone-view {
  display: none;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

.status-tip {
  position: absolute;
  margin: 5px 5px 5px 15px;
}

.dot {
  position: relative;
  display: inline-block;
  &::before {
    content: '';
    position: absolute;
    top: -10px;
    left: -10px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
  }
}

.unconnect-dot {
  .dot::before {
    background-color: var(--el-color-info);
  }
}

.disconnect-dot {
  .dot::before {
    background-color: var(--el-color-error);
  }
}

.exceedLimit-dot {
  .dot::before {
    background-color: var(--el-color-error);
  }
}

.connecting-dot {
  .dot::before {
    background-color: var(--el-color-warning);
  }
}

.connected-dot {
  .dot::before {
    background-color: var(--el-color-success);
  }
}

@media screen and (min-width: 720px) {
  .connected {
    &:hover {
      transform: translate(0, -3px);
      cursor: pointer;
      transition: all 250ms;
      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
    }
  }
}

@media screen and (max-width: 720px) {
}
</style>
<style lang="less">
.phone-dialog {
  width: 85vw;
  height: 80vh;
  .wallpaper {
    width: 80vw;
    height: 70vh;
    display: flex;
    justify-content: center;
  }
  .PORTRAIT {
    width: 45rem;
  }

  .LANDSCAPE {
    height: 100rem;
  }
}
</style>
